#pragma once
#include "GameObject.h"
#include <memory>
#include <vector>

namespace dxroids
{
   class SoundManager;

   class Ship : public GameObject
   {

   public:

      struct Attributes
      {
         float ThrustMagnitude;
         float MaximumVelocity;
         float ShotVelocity;
         float MaximumNumberOfShots;
         float MaximumShotDistance;         
      };
      
      Ship(Vector const & pos, float _scale, float _bounding_radius, Attributes const & _attrs);      
      
   public:

      void EnableThrust(std::shared_ptr<SoundManager> & _sound_manager);
      void DisableThrust(std::shared_ptr<SoundManager> & _sound_manager);

      void SetFireShotEnabled(bool _b);

      bool FireShot(std::shared_ptr<SoundManager> const & _sound_manager);
      bool IsShotHittingObject(GameObject const & _rhs) const;

      virtual std::unique_ptr<GameObject> Destroy(std::shared_ptr<SoundManager> const & _sound_manager) = 0;      
      
      virtual void Render(RenderContext const & _ctx) override;

      virtual void UpdateFrame(GameTime const & _timer, ClippingInformation const & _clip, 
         bool * _wrap_horizontal, bool * _wrap_vertical) override;

   private:

      virtual DXROIDS_COM_PTR<ID2D1Geometry> CreateGeometry(
         DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale) override;

   protected:

      virtual DXROIDS_COM_PTR<ID2D1Geometry> CreateShipGeometry(
         DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale) = 0;

      virtual DXROIDS_COM_PTR<ID2D1Geometry> CreateThrustGeometry(
         DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale) = 0;

      virtual Vector GetNextShotPosition() const;
      virtual float GetNextShotDirection() const;      

      class Photon : public GameObject
      {         

      public:
         
         Photon(Vector const & _pos, Vector _velocity, float _max_distance);

         virtual void UpdateFrame(GameTime const & _timer, ClippingInformation const & _clip, 
         bool * _wrap_horizontal, bool * _wrap_vertical) override;         

      protected:

         virtual DXROIDS_COM_PTR<ID2D1Geometry> CreateGeometry(
            DXROIDS_COM_PTR<ID2D1Factory> const & _factory, float _scale) override;

         virtual bool IntersectsWithGeometry(DXROIDS_COM_PTR<ID2D1Geometry> const & _rhs) const override;

      private:

         float max_distance_;
         int32_t num_frames_;
         int32_t max_frames_;
      };      

   private:

      bool thrust_enabled_;
      bool fire_shot_enabled_;
      Attributes attrs_;     

      std::vector<std::unique_ptr<Photon>> shots_fired_;
      std::vector<std::unique_ptr<Photon>> shots_ready_to_fire_;

      DXROIDS_COM_PTR<ID2D1PathGeometry> thrust_gemoetry_;

   };
}

inline void dxroids::Ship::SetFireShotEnabled(bool _b)
{
   fire_shot_enabled_ = _b;
}